package com.qingdai.service.impl.Security;

import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.qingdai.emuns.*;
import com.qingdai.mapper.UserMapper;
import com.qingdai.service.UserRoleService;
import jakarta.annotation.Resource;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleService userRoleService;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        MPJLambdaWrapper wrapper = new MPJLambdaWrapper<>();
        wrapper.eq("username", username);
        User user = userMapper.selectOne(wrapper);
        if (user == null) {
            //只有在抛出异常时才认定为登录失败
            throw new UsernameNotFoundException("用户不存在");
        }

//            查询角色 权限 集合
        List<RoleDTO> rolesList = userRoleService.getRolesByUserId(user.getId());
        List<PermissionDTO> permissionList = userRoleService.getPermissionsByUserId(user.getId());

//          定义一个字符串泛型的List集合对象
        List<String> authorities = new ArrayList<>();
        for (RoleDTO role : rolesList) {
//          角色名称纳入的权限管理，必须增加前缀ROLE_
            authorities.add("ROLE_" + role.getName());
        }
        for (PermissionDTO permission : permissionList) {
//          权限字符串描述，不需要特定的任何前后缀。
            authorities.add(permission.getPermit());
        }

        /*
         * 如果 loadUserByUsername未抛出异常，则校验返回值中保存的密码和请求参数密码是否匹配。
         * 获取spring容器中的PasswordEncoder类型对象，调用方法matches比较密码。
         * 如果密码比较结果是true，登录成功。
         * 如果密码比较结果是false，登录失败，重定向到/login?error。
         */
        org.springframework.security.core.userdetails.User result =
                new org.springframework.security.core.userdetails.User(
                        username, //用户名
                        user.getPassword(), //登录用户的密码，是服务端保存到密文
                        AuthorityUtils.createAuthorityList(String.valueOf(authorities))//通过工具，把字符串权限转换成Security定义的权限

                );


        return result;
//        return new LoginUser(user);
    }

}

